#ifndef GA_H_
#define GA_H_



#ifndef WIN32
#include "../F2-Sd-W/F2-Sd-W.h"
#include "../Model/lib.h"
#else
#include "..\\F2-Sd-W\\F2-Sd-W.h"
#include "..\\Model\\lib.h"
#endif


//种群数量
#define POP_SIZE  1200

//染色体长度=需求长度
#define CHROMOSOME_LENGTH n_0

//最大进化代数
#define MAX_GENERATION	1500

//变异概率
#define MUTATION_PROBABILITY	0.1

//交叉概率
#define CROSSOVER_PROBABILITY	0.9

#define Niche_N POP_SIZE/20
//to be memoried N chromosomes

#define L   CHROMOSOME_LENGTH/1.5
//the distance gap

#define OBJ_PENALTY     1000.0
//目标值的惩罚值



int the1st(int value,int data[],int length);//return the index in data[] of the element = value
int the1stValid(int data[],int length);//第一个合法的元素


class Chromosome{
		int Gene[CHROMOSOME_LENGTH];
		//代数，初始为0,不大于max_generation
		int generation;
		int ID;
		//the object fuction value
		double obj_value;
		//the fitness value
		double fitness;
	public:
		static int now_max_id;
		int getID();
		//直接设置一个染色体
		void setChromosome(int data[]);
		//随机初始化一个染色体
		void randInit();
		//目标值计算
		double calcOjbectFun();
		//直接设置染色体中的一个基因
		void setGene(int zero_based_posision, int value);
		//直接设置某一段基因的值
		void setGene(int zero_based_position, int length, int date[]);
		//读取基因值
		int getGene(int zero_based_posision);
		//赋值操作
		void operator =(Chromosome& chrmsA);
		//变异操作
		void mutation();
		//打印
		void show();
		//get objective fuction value
		double getObjValue();
		//get the fitness value
		double getFitness();
		void setFitness(double value);
		
		void adjustObjValue(double value);
		
		Chromosome();
		
		~Chromosome();
};

class Population{
	Chromosome chrom[POP_SIZE];
	int Generation;
	double current_best_obj_value;
	int the_best_one;
	double Sigma_fit;
	
	int the_worst_one;
	
	Chromosome global_best;
	double theObjs[MAX_GENERATION+1];
	
	public:
		Population();
		~Population();
		void CrossOver(Chromosome* A, Chromosome* B);//交叉操作
		void Select();//选择操作
		void CalcFitness();
		void test();
		void show();
		void main_proc();
		
		void GA();
		
	/////for Niche GA
		Chromosome Niche_Chrom[POP_SIZE+Niche_N];
		Chromosome TempChrom[Niche_N];
		void NicheGA();
		void NicheGA_main_proc();
		void SortThem(Chromosome C[], int SIZE);
		double CalcDistance(Chromosome* A, Chromosome* B);
		void Niche_CalcFitness();
		void SetNewFitness(Chromosome C[], int SIZE);
	/////////////////////////
		
		void ShowBest();
};

class tempVector{
    Chromosome Temp[POP_SIZE];
    int count;
   public:
    void Add(Chromosome& A);
    void Clear();
    void CopyTo(Chromosome D[]);
    tempVector();
    ~tempVector();
};

class dynArray{
    int count;
    public:
    int data[CHROMOSOME_LENGTH];
    dynArray();
    ~dynArray();
    void insert(int pos,int Value);
    int getCount();
    bool isValid(int value,int pos);
};

#endif
